
package com.example.automotive.util;

import android.util.Log;

import com.example.automotive.MainActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class DataManager {

    public final String TAG;
    private MainActivity mainActivity;

    public DataManager(String tag, MainActivity mainActivity){
        this.TAG = tag;
        this.mainActivity = mainActivity;
    }

    // 上传图片到服务器的方法
    public void uploadDataToServer(String filePath, String sensorDataJson) {
        // 创建一个新线程来执行网络操作，防止阻塞主线程
        new Thread(() -> {
            // 创建 OkHttpClient 实例，用于发送 HTTP 请求
            OkHttpClient client = new OkHttpClient();

            // 创建一个 File 对象，表示要上传的图片文件
            File file = new File(filePath);

            // 创建 RequestBody 对象，用于封装文件数据
            // MediaType.parse("image/jpeg") 表示文件的 MIME 类型为 JPEG 图片
            RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
            RequestBody jsonBody = RequestBody.create(MediaType.parse("application/json"), sensorDataJson);

            // 创建 MultipartBody.Builder 对象，用于构建 multipart/form-data 请求体
            RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM) // 设置请求体类型为 multipart/form-data
                    .addFormDataPart("file", file.getName(), fileBody) // 添加文件部分
                    .addFormDataPart("sensorData", sensorDataJson)
                    .build();

            // 创建 Request 对象，表示一个 HTTP 请求
            // .url(SERVER_URL) 设置请求的 URL
            // .post(requestBody) 设置请求方法为 POST，并将请求体设置为 requestBody
            Request request = new Request.Builder()
                    .url(Config.UPLOAD_URL)
                    .post(requestBody)
                    .build();

            // 使用 OkHttpClient 发送请求并获取响应
            try (Response response = client.newCall(request).execute()) {
                // 如果响应成功（HTTP 状态码 2xx），则输出成功日志
                if (response.isSuccessful()) {
                    Log.d(TAG, "Image upload succeeded: " + response.message());
                } else {
                    // 如果响应失败，则输出失败日志
                    Log.e(TAG, "Image upload failed: " + response.message());
                }
            } catch (IOException e) {
                // 处理上传过程中发生的 IO 异常，并输出错误日志
                Log.e(TAG, "Image upload error", e);
                // 上传失败时保存文件路径，以便稍后再试
                saveFailedUpload(filePath, sensorDataJson);
            }
        }).start(); // 启动新线程
    }

    // 将图像保存到本地的方法
    public String saveImageToLocal(byte[] bytes, long timestamp) {
        // 创建保存图片的目录
        File dir = new File(mainActivity.getFilesDir(), "autodata");
//        System.out.println(dir.getAbsolutePath());
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                Log.e(TAG, "Failed to create directory: " + dir.getAbsolutePath());
                return null;
            }
        }

        // 使用时间戳创建文件名
        String fileName = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date(timestamp)) + ".jpg";
        File file = new File(dir, fileName);

        // 将字节数组写入文件
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(bytes);
            Log.d(TAG, "Image saved to: " + file.getAbsolutePath());
            return file.getAbsolutePath();
        } catch (IOException e) {
            Log.e(TAG, "Failed to save image", e);
            return null;
        }
    }

    // 保存上传失败的文件路径到本地
    public void saveFailedUpload(String filePath, String sensorDataJson) {
        // 实现保存逻辑，例如保存到数据库或文件中
    }

    // 定期检查并上传失败的文件
    public void uploadFailedFiles() {
        // 实现检查和上传逻辑
    }

    public void startFailedUploadCheckTask() {
        // 启动定期检查任务，上传失败的文件
    }

    public void downloadModel()
    {
        System.out.println("========================================================");
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url(Config.DOWNLOAD_URL)
                .build();

        client.newCall(request).enqueue(new Callback(){
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "Model download failed: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println("----------------------------------------------------------------------------");
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response);
                }

                File modelFile = new File(mainActivity.getFilesDir(), Config.MODEL_NAME);
                try (InputStream is = response.body().byteStream();
                     FileOutputStream fos = new FileOutputStream(modelFile)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        fos.write(buffer, 0, bytesRead);
                    }
                    Log.d(TAG, "Model downloaded to: " + modelFile.getAbsolutePath());
                }
                catch (IOException e){
                    Log.e(TAG, "Error writing model file: " + e.getMessage());
                }
            }
        });
    }
}
